package com.ericsson.smart;

import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ericsson.smart.dao.FactDAOold;
import com.ericsson.smart.dao.FactDAO;
import com.ericsson.smart.dao.GeographyDimensionsDAO;
import com.ericsson.smart.dto.GeoDrilldown;
import com.ericsson.smart.model.BreadCrumb;
import com.ericsson.smart.model.Dimension;
import com.ericsson.smart.model.Report;
import com.ericsson.smart.test.TestFetchMeterData;
import com.ericsson.smart.test.TestReportLoad;
import com.google.visualization.datasource.DataSourceHelper;
import com.google.visualization.datasource.DataSourceRequest;
import com.google.visualization.datasource.base.DataSourceException;
import com.google.visualization.datasource.base.TypeMismatchException;
import com.google.visualization.datasource.datatable.ColumnDescription;
import com.google.visualization.datasource.datatable.DataTable;
import com.google.visualization.datasource.datatable.value.ValueType;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {

	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

	/**
	 * Simply selects the home view to render by returning its name.
	 */

	@Autowired
	UtilityStartUpListener<String> startUpClass;
	@Autowired
	UtilityCommon utilCommon;
	
	
//	UtilityStartUpListener<String> startUpClass = new UtilityStartUpListener<String>();

//	List<String> reportNames = UtilityCommon.getInstance().getReportNames();

	String reportName = "TIME-GEO-CONSUMPTION-REPORT";
	String alarmReport = "ALARM-REPORT";

	Report report;
	
	@PersistenceContext
	EntityManager em;
	
	@Autowired
	FactDAO factDaoMod;

	// startUpCla

	// List<String> reportDimensionDetails;
	// String reportName = reportNames.get(0);
	// reportDimensionDetails =
	// UtilityCommon.getInstance().getReportDimensionDetails(
	// reportName.trim());
	// System.out.println("REPORT-DIMENSIONS: SIZE:" +
	// reportDimensionDetails.size()
	// + ": VALUES: " + reportDimensionDetails);

	// TestFetchMeterData.generateReport(report);

	// REPORT-DIMENSIONS : DIM_TIME, DIM_GEOGRAPHY
	// String dimensionName = "DIM_TIME";
	// report = TestReportLoad.drillDownReport(report, dimensionName, 4);

	@RequestMapping(value = "/aaa", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);

		utilCommon.getReportMetaData();
		utilCommon.getHierarchyMetaData();

		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG,
				locale);

		String formattedDate = dateFormat.format(date);

		model.addAttribute("serverTime", formattedDate);

		return "home";
	}
	@Transactional
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String startapp(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", em);
		logger.info("UtilityStartUpListener is {}.", startUpClass);
		Query q = em.createNativeQuery("Select * from DIM_GEOGRAPHY");
		logger.info("UtilityStartUpListener is {}.", q.getResultList());
		

		return "home";
	}

	@RequestMapping(value = "/ValidateUser", method = RequestMethod.GET)
	public @ResponseBody
	UserInfo validation(HttpServletRequest req, HttpServletResponse resp) {
		logger.info("validating user ");
		String emailID = req.getParameter("emailid");
		String password = req.getParameter("password");
		logger.info(emailID);
		logger.info(password);

		UserInfo u = new UserInfo();
		if (emailID.equals("avishek7@gmail.com") && password.equals("123")) {
			logger.info("authentication successful ");

			u.setName("Hello Abhishek");
		} else
			u.setName("Hello Guest");

		return u;
	}

	@RequestMapping(value = "/getChartData", method = RequestMethod.GET)
	public void chartData(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("Parameter Received----" + req.getParameter("Vegetarian?"));
		DataTable data = new DataTable();
		ArrayList<ColumnDescription> cd = new ArrayList<ColumnDescription>();
		cd.add(new ColumnDescription("name", ValueType.TEXT, "Animal name"));
		cd.add(new ColumnDescription("population", ValueType.NUMBER, "Population size"));
		cd.add(new ColumnDescription("vegeterian", ValueType.BOOLEAN, "Vegetarian?"));

		data.addColumns(cd);

		// Fill the data table.
		try {
			data.addRowFromValues("Kiwi", 100, true);
			data.addRowFromValues("Sloth", 300, true);
			data.addRowFromValues("Leopard", 50, false);
			data.addRowFromValues("Tiger", 80, false);
		} catch (TypeMismatchException e) {
			System.out.println("Invalid type!");
		}
		try {
			DataSourceHelper.setServletResponse(data, new DataSourceRequest(req), resp);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DataSourceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.info("..............." + resp.toString());

	}

	@RequestMapping(value = "/getPieData", method = RequestMethod.GET)
	public void pieData(HttpServletRequest req, HttpServletResponse resp) {

		DataTable data = new DataTable();
		ArrayList<ColumnDescription> cd = new ArrayList<ColumnDescription>();
		cd.add(new ColumnDescription("name", ValueType.TEXT, "Animal name"));
		cd.add(new ColumnDescription("population", ValueType.NUMBER, "Population size"));

		data.addColumns(cd);

		// Fill the data table.
		try {
			data.addRowFromValues("Kiwi", 100);
			data.addRowFromValues("Sloth", 300);
			data.addRowFromValues("Leopard", 50);
			data.addRowFromValues("Tiger", 80);
		} catch (TypeMismatchException e) {
			System.out.println("Invalid type!");
		}
		try {
			DataSourceHelper.setServletResponse(data, new DataSourceRequest(req), resp);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DataSourceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.info("..............pir." + resp.toString());

	}

	@RequestMapping(value = "/getColumnData", method = RequestMethod.GET)
	public @ResponseBody
	AjaxResponse currDim(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("Inside currDim ");
		String currDim = request.getParameter("currentDim");
		String currVal = request.getParameter("currentVal");
		String condition = request.getParameter("condition");
		/*
		 * currDim = "GEO_CITY"; currVal = "sub1"; condition = "city = 'Kolkata'";
		 */

		if (currDim != "") {
			logger.info("currDim is not null");
			logger.info("currDim is " + currDim);
			logger.info("currVal is " + currVal);
			String nextDimcolumn = GeoDrilldown.valueOf(currDim).getNextDimension().getColName();
			condition = condition + " and " + nextDimcolumn + " = '" + currVal + "'";
			currDim = GeoDrilldown.valueOf(currDim).getNextDimension().getName();

			logger.info(condition);

		} else {
			currDim = "GEO_CITY";
			currVal = "'Kolkata'";

			logger.info("currDim is " + currDim);
			logger.info("currVal is " + currVal);
			GeoDrilldown g = GeoDrilldown.valueOf(currDim);
			String curDimColName = g.getColName();
			logger.info("column name is:" + curDimColName);

			condition = curDimColName + " = " + currVal;
		}
		logger.info("going to create Geography dimensions object");
		GeographyDimensionsDAO geoDao = new GeographyDimensionsDAO();

		logger.info("select query");
		Object[][] data = geoDao.select(currDim, condition);

		AjaxResponse dataResponse = new AjaxResponse();
		dataResponse.setData(data);

		logger.info(currVal);
		logger.info(currDim);
		logger.info(condition);
		dataResponse.setCurrentValue(currVal);
		dataResponse.setCurrentDimension(currDim);
		dataResponse.setCondition(condition);

		return dataResponse;
	}

	/*
	 * @RequestMapping(value = "/chartview", method = RequestMethod.GET) public String
	 * chartview(Locale locale, Model model) { logger.info("Wchart veiw...1"); return "chartview"; }
	 */

	@RequestMapping(value = "/cmpchart", method = RequestMethod.GET)
	public String cmpchart(Model model) {
		model.addAttribute("firstReport", report);
		logger.info("cmpchart veiw...2"+report.getName()+"...."+report.getDimensionCount());
		return "cmpchart";
	}

	@RequestMapping(value = "/ctzchart", method = RequestMethod.GET)
	public String ctzchart(Model model, HttpSession session) {
		report= loadReport(reportName);
		model.addAttribute("firstReport", report);
		session.setAttribute("consumptionReport", report);
		
		report= loadReport(alarmReport);		
		model.addAttribute("alarmReport", report);
		session.setAttribute("alarmReport", report);
	
		//model.addAttribute("displayLabelMap", getDisplayLabelMap());
		// logger.info("ctzchart veiw...2: REPORT : " + report);
		// session.setAttribute("firstReport", report);
		return "ctzchart";
	}

	@RequestMapping(value = "/dashboard", method = RequestMethod.GET)
	public String dashboard(Model model) {
		logger.info("dashboard veiw...2");
		return "dashboard";
	}

	@RequestMapping(value = "/histchart", method = RequestMethod.GET)
	public String histchart(Model model) {
		logger.info("histchart veiw...2");
		return "histchart";
	}

	@RequestMapping(value = "/stdchart", method = RequestMethod.GET)
	public String stdchart(Model model) {
		logger.info("stdchart veiw...2");
		return "stdchart";
	}

	@RequestMapping(value = "/chgpassword", method = RequestMethod.GET)
	public String chgpassword(Model model) {
		logger.info("chgpassword veiw...2");
		return "chgpassword";
	}

	@RequestMapping(value = "/updprofile", method = RequestMethod.GET)
	public String updprofile(Model model) {
		logger.info("updprofile veiw...2");
		return "updprofile";
	}

	@RequestMapping(value = "/stdchartsetting", method = RequestMethod.GET)
	public String stdchartsetting(Model model) {
		logger.info("stdchartsetting veiw...2");
		return "stdchartsetting";
	}

	@RequestMapping(value = "/chartpopup", method = RequestMethod.GET)
	public String chartpopup(Model model) {
		logger.info("chartpopup veiw...2");
		return "chartpopup";
	}

	@RequestMapping(value = "/getAvailableValue", method = RequestMethod.POST)
	public String getNextLevelValues(HttpServletRequest request, HttpServletResponse response) {
		logger.info("Enter into getAvailableValue method...");
		logger.info("value of request ..." + request);
		request.getParameterNames();
		logger.info("value of getSelectedValue is... " + request.getParameterNames());
		for (Object obj : request.getParameterMap().keySet()) {
			logger.info("Objectss..ket..." + obj);

		}

		// logger.info("value of getSelectedValue is... " + request.getParameterMap());
		ArrayList<String> list = new ArrayList<String>();
		list.add(0, "Kolkata");
		list.add(1, "SaltLake");
		list.add(2, "Howrah");

		String str = "Kolkata,SaltLake,Howrah";
		return str;

	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/getDimensionLevelData", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody
	List<String> getDimensionLevelData(
			@RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
			HttpServletRequest request, HttpServletResponse response, HttpSession session) {
		logger.info("getDimensionLevelData3..:" + json);
		// //Dimension drillDownDimension;
		String dimensionName = "";
		List<String> nextOrderSelectionValues = null;
		String nextOrderLevelName = "";
		String currentOrderLevelName = "";
		LinkedHashMap<String, Object> breadCrumbMap = null;

		for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
			logger.info(entry.getValue() + ":" + entry.getKey());

			BreadCrumb breadCrumb = new BreadCrumb();
			breadCrumb.setDimension(entry.getKey());
			breadCrumb.setDimensionValueMap((LinkedHashMap<String, Object>) entry.getValue());

			dimensionName = entry.getKey();
			breadCrumbMap = entry.getValue();
			for (Entry<String, Object> entrySub : ((LinkedHashMap<String, Object>) entry.getValue())
					.entrySet()) {
				currentOrderLevelName = entrySub.getKey().trim();
				System.out.println("Sub Key" + entrySub.getKey() + "::" + entrySub.getValue());
			}
		}
		nextOrderLevelName = utilCommon.getNextHierarchyLevelName(dimensionName,
				currentOrderLevelName);
		nextOrderSelectionValues = utilCommon.getNextOrderSelectionValues(
				dimensionName, nextOrderLevelName, breadCrumbMap);
		logger.info("CurrentSelectionLeveleName: " + currentOrderLevelName);
		logger.info("NextSelectionLeveleName: " + nextOrderLevelName);
		logger.info("NextOrderSelectionValues:" + nextOrderSelectionValues);
		return nextOrderSelectionValues;

	}
	
	@RequestMapping(value = "/getCustomizedAlarmReport", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody
	Map<String, Float> getCustomizedAlarmReport(
			@RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
			HttpServletRequest request, HttpServletResponse response, HttpSession session) {
		logger.info("-----------------------" + "getCustomizedAlarmReport():"
				+ "-----------------------");
		logger.info("getCustomizedAlarmReport-JSON:" + json);		
		
		String dimensionName = "";
		String selectedDimension = "";
		String selectedLevel = "";
		LinkedHashMap<String, Object> breadCrumbMap = null;

		Report report = loadReport(alarmReport);
		for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
			logger.info("getCustomizedAlarmReport-DATA:" + entry.getValue() + ":"
					+ entry.getKey());
			dimensionName = entry.getKey();
			breadCrumbMap = entry.getValue();
			if (report.getDimension(dimensionName) != null) {
				report.updateBreadCrumb(dimensionName, breadCrumbMap);
			} else {
				for (Entry<String, Object> level : breadCrumbMap.entrySet()) {
					if (level.getValue() == null) {
						selectedDimension = dimensionName;
						selectedLevel = level.getKey();
						Dimension dimension = new Dimension();
						dimension.setName(dimensionName);
						dimension.setNumberOfLevels(1);
						dimension.setCurrentSelectionName(selectedLevel);
						report.addDimension(dimension);
						report.updateBreadCrumb(dimensionName, null);
						break;
					} else {
						Dimension dimension = new Dimension();
						dimension.setName(dimensionName);
						dimension.setNumberOfLevels(breadCrumbMap.size());
						dimension.setCurrentSelectionName(level.getKey());
						report.addDimension(dimension);
						report.updateBreadCrumb(dimensionName, breadCrumbMap);
					}
				}
			}
		}
		report.setAsFirstDimension(selectedDimension);
		List<String> dimList = report.getDimensionList();
		List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();

		boolean nextLevelGroupingRequired = false;

		if (dimList.get(0).equalsIgnoreCase("DIM_GEOGRAPHY")) {
			nextLevelGroupingRequired = true;
		}
		//FactDAO factDaoMod = new FactDAO();
		Map<String, Float> factDataMap = factDaoMod.fetchAlarmData(dimDataMapList, dimList,
				report.getAggregateOperation(), nextLevelGroupingRequired, String.class);
		return factDataMap;
		
		
	}
	

	@RequestMapping(value = "/getCustomizedConsumptionReport", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody
	Map<String, Float> getCustomizedConsumptionReport(
			@RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
			HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) {
		logger.info("-----------------------" + "getCustomizedConsumptionReport():"
				+ "-----------------------");
		logger.info("getCustomizedConsumptionReport-JSON:" + json);

		String dimensionName = "";
		String selectedDimension = "";
		String selectedLevel = "";
		LinkedHashMap<String, Object> breadCrumbMap = null;

		System.out.println("Report From Session:"+session.getAttribute("consumptionReport"));
		
		Report report = loadReport(reportName);
		
		
		for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
			logger.info("getCustomizedConsumptionReport-DATA:" + entry.getValue() + ":"
					+ entry.getKey());
			dimensionName = entry.getKey();
			breadCrumbMap = entry.getValue();
			if (report.getDimension(dimensionName) != null) {
				System.out.println("Inside if part.....");
				report.updateBreadCrumb(dimensionName, breadCrumbMap);
			} else {
				for (Entry<String, Object> level : breadCrumbMap.entrySet()) {
					System.out.println("Enter first if part...");
					if (level.getValue() == null) {
						selectedDimension = dimensionName;
						selectedLevel = level.getKey();
						Dimension dimension = new Dimension();
						dimension.setName(dimensionName);
						dimension.setNumberOfLevels(1);
						dimension.setCurrentSelectionName(selectedLevel);
						report.addDimension(dimension);
						report.updateBreadCrumb(dimensionName, null);
						break;
					} else {
						System.out.println("Enter first else part...");
						Dimension dimension = new Dimension();
						dimension.setName(dimensionName);
						dimension.setNumberOfLevels(breadCrumbMap.size());
						dimension.setCurrentSelectionName(level.getKey());
						report.addDimension(dimension);
						report.updateBreadCrumb(dimensionName, breadCrumbMap);
					}
				}
			}
		}
		report.setAsFirstDimension(selectedDimension);
		List<String> dimList = report.getDimensionList();
		List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();

		boolean nextLevelGroupingRequired = false;

		if (dimList.get(0).equalsIgnoreCase("DIM_GEOGRAPHY")) {
			System.out.println("Inside DIM_CUSTOMER of homeController...");
			nextLevelGroupingRequired = true;
		}
		//FactDAO factDaoMod = new FactDAO();
		Map<String, Float> factDataMap = factDaoMod.fetchReportData(dimDataMapList, dimList,
				report.getAggregateOperation(), nextLevelGroupingRequired, String.class);
		return factDataMap;
	}
	

	
	
	@RequestMapping(value = "/getComparisonConsumptionReport", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody
	Map<String,Map<String, Float>> getComparisonConsumptionReport(
			@RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
			HttpServletRequest request, HttpServletResponse response, HttpSession session) {
		logger.info("-----------------------" + "getComparisonConsumptionReport():"
				+ "-----------------------");
		logger.info("getComparisonConsumptionReport-JSON:" + json);

		String dimensionName = "";
		String suffix = "";
		String comparedDimension = "";
		LinkedHashMap<String, Object> breadCrumbMap = null;

		Report frmReport = loadReport(reportName);
		Report toReport = loadReport(reportName);
		
		for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
			logger.info("getComparisonConsumptionReport-DATA:" + entry.getValue() + ":"
					+ entry.getKey());
			dimensionName = entry.getKey();
			breadCrumbMap = entry.getValue();
			
			if (report.getDimension(dimensionName) != null) {
				frmReport.updateBreadCrumb(dimensionName, breadCrumbMap);
				toReport.updateBreadCrumb(dimensionName, breadCrumbMap);
			} else {
				dimensionName = entry.getKey().substring(0,entry.getKey().lastIndexOf("_"));
				comparedDimension = dimensionName;
				suffix = entry.getKey().substring(entry.getKey().lastIndexOf("_")+1);
				if (report.getDimension(dimensionName) != null) {
					if(suffix.equalsIgnoreCase("FROM")) {
						frmReport.updateBreadCrumb(dimensionName, breadCrumbMap);
					} else if(suffix.equalsIgnoreCase("TO")) {
						toReport.updateBreadCrumb(dimensionName, breadCrumbMap);
					}
				}
			}
		}
		
		List<String> dimList; 
		List<Map<String, Object>> dimDataMapList ;
		
		dimList = frmReport.getDimensionList();
		dimDataMapList = frmReport.getDimensionDataMapList();

		boolean nextLevelGroupingRequired = false;

		if (dimList.get(0).equalsIgnoreCase("DIM_GEOGRAPHY")) {
			nextLevelGroupingRequired = true;
		}
		
		//FactDAO factDaoMod = new FactDAO();
		Map<String, Float> frmReportFactDataMap = factDaoMod.fetchReportData(dimDataMapList, dimList,
				frmReport.getAggregateOperation(), nextLevelGroupingRequired, String.class);
		
		dimList = toReport.getDimensionList();
		dimDataMapList = toReport.getDimensionDataMapList();
		
		Map<String, Float> toReportFactDataMap = factDaoMod.fetchReportData(dimDataMapList, dimList,
				toReport.getAggregateOperation(), nextLevelGroupingRequired, String.class);
		
		HashMap<String,Map<String, Float>> returnMap = new HashMap<String,Map<String, Float>>();
		returnMap.put(comparedDimension+"_FROM", frmReportFactDataMap);
		returnMap.put(comparedDimension+"_TO", toReportFactDataMap);
		
		return returnMap;
	}

	public HashMap<String,String> getDisplayLabelMap() {
		HashMap<String, String> displayLabelMap = new HashMap<String, String>();
		displayLabelMap.put("TIME-GEO-CONSUMPTION-REPORT",
				"Consumption Report in Time & Geography Dimension");
		displayLabelMap.put("DIM_GEOGRAPHY", "Geography Dimesnion Details");
		displayLabelMap.put("DIM_TIME", "Time Deimesion Details");
		return displayLabelMap;
	}

	// @RequestMapping(value = "/getReportData", method = { RequestMethod.POST, RequestMethod.GET })
	// public @ResponseBody
	// // BreadCrumb getDimensionLevelData3(@RequestBody HashMap<String, String> json,
	// // HttpServletRequest request,
	// Map<String, Map<String, Float>> getReportData(
	// @RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
	// HttpServletRequest request, HttpServletResponse response, HttpSession session) {
	// logger.info("getReportData..:" + json);
	// // //Dimension drillDownDimension;
	// String dimensionName = "";
	// LinkedHashMap<String, Object> breadCrumbMap = null;
	//
	// // Report report = loadReport(reportName);
	//
	// for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
	// logger.info("getReportData..:" + entry.getValue() + ":" + entry.getKey());
	// dimensionName = entry.getKey();
	// breadCrumbMap = entry.getValue();
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// }
	// logger.info("Report:" + report);
	//
	// List<String> dimList = report.getDimensionList();
	// List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	//
	// FactDAO factDao = new FactDAO();
	// Map<String, Float> factDataMap1 = factDao.fetchReportData(dimDataMapList, dimList,
	// report.getAggregateOperation(), true, dimList.get(0), String.class);
	// // System.out.println("REPORT-DATA-1: " + factDataMap1);
	//
	// Map<String, Float> factDataMap2 = factDao.fetchReportDataMod(dimDataMapList, dimList,
	// report.getAggregateOperation(), String.class);
	// // System.out.println("REPORT-DATA-2: " + factDataMap2);
	//
	// Map<String, Map<String, Float>> factDataMap = new HashMap<String, Map<String, Float>>();
	// factDataMap.put("DIM_GEOGRAPHY", factDataMap1);
	// factDataMap.put("DIM_SUBSTATION", factDataMap2);
	//
	// return factDataMap;
	// // return factDataMap1;arg0
	// }

	// @RequestMapping(value = "/getGeoDimensionReport", method = { RequestMethod.POST,
	// RequestMethod.GET })
	// public @ResponseBody
	// Map<String, Float> getGeoDimensionReport(
	// @RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
	// HttpServletRequest request, HttpServletResponse response, HttpSession session) {
	// logger.info("-----------------------" + "getGeoDimensionReport()"
	// + "-----------------------");
	// logger.info("getGeoDimensionReport-JSON:" + json);
	// // //Dimension drillDownDimension;
	// String dimensionName = "";
	// LinkedHashMap<String, Object> breadCrumbMap = null;
	// for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
	// logger.info("getGeoDimensionReport-DATA:" + entry.getValue() + ":" + entry.getKey());
	// dimensionName = entry.getKey();
	// breadCrumbMap = entry.getValue();
	// if (report.getDimension(dimensionName) != null) {
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// }
	// }
	// // logger.info("Report:"+report);
	//
	// List<String> dimList = report.getDimensionList();
	// List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	//
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportData(dimDataMapList, dimList,
	// // report.getAggregateOperation(), true, dimList.get(0), String.class);
	// // return factDataMap1;
	//
	// FactDAOMod factDaoMod = new FactDAOMod();
	// Map<String, Float> factDataMap1 = factDaoMod.fetchReportData(dimDataMapList, dimList,
	// report.getAggregateOperation(), true, String.class);
	// return factDataMap1;
	//
	// }
	//
	// @RequestMapping(value = "/getSubStationDimensionReport", method = { RequestMethod.POST,
	// RequestMethod.GET })
	// public @ResponseBody
	// Map<String, Float> getSubStationDimensionReport(
	// @RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
	// HttpServletRequest request, HttpServletResponse response, HttpSession session) {
	// logger.info("-----------------------" + "getSubStationDimensionReport()"
	// + "-----------------------");
	// logger.info("getSubStationDimensionReport-JSON:" + json);
	// // //Dimension drillDownDimension;
	// String dimensionName = "";
	// String selectedDimension = "";
	// String selectedLevel = "";
	// LinkedHashMap<String, Object> breadCrumbMap = null;
	//
	// Report report = loadReport(reportName);
	// // Report report = this.report;
	//
	// for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
	// logger.info("getSubStationDimensionReport-DATA:" + entry.getValue() + ":"
	// + entry.getKey());
	// dimensionName = entry.getKey();
	// breadCrumbMap = entry.getValue();
	// if (report.getDimension(dimensionName) != null) {
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// } else {
	// for (Entry<String, Object> level : breadCrumbMap.entrySet()) {
	// if (level.getValue() == null) {
	// selectedDimension = dimensionName;
	// selectedLevel = level.getKey();
	// Dimension dimension = new Dimension();
	// dimension.setName(dimensionName);
	// dimension.setNumberOfLevels(1);
	// dimension.setCurrentSelectionName(selectedLevel);
	// report.addDimension(dimension);
	// report.updateBreadCrumb(dimensionName, null);
	// break;
	// }
	// }
	// }
	// }
	// report.setAsFirstDimension(selectedDimension);
	// // List<String> dimList = report.getDimensionList();
	// // List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportDataMod1(dimDataMapList, dimList,
	// // report.getAggregateOperation(), String.class);
	//
	// List<String> dimList = report.getDimensionList();
	// List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	//
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportData(dimDataMapList, dimList,
	// // report.getAggregateOperation(), false, dimList.get(0), String.class);
	// // return factDataMap1;
	//
	// FactDAOMod factDaoMod = new FactDAOMod();
	// Map<String, Float> factDataMap1 = factDaoMod.fetchReportData(dimDataMapList, dimList,
	// report.getAggregateOperation(), false, String.class);
	// return factDataMap1;
	// }
	//
	// @RequestMapping(value = "/getCustomerDimensionReport", method = { RequestMethod.POST,
	// RequestMethod.GET })
	// public @ResponseBody
	// Map<String, Float> getCustomerDimensionReport(
	// @RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
	// HttpServletRequest request, HttpServletResponse response, HttpSession session) {
	// logger.info("-----------------------" + "getCustomerDimensionReport()"
	// + "-----------------------");
	// logger.info("getCustomerDimensionReport-JSON:" + json);
	// // //Dimension drillDownDimension;
	// String dimensionName = "";
	// String selectedDimension = "";
	// String selectedLevel = "";
	// LinkedHashMap<String, Object> breadCrumbMap = null;
	//
	// Report report = loadReport(reportName);
	//
	// for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
	// logger.info("getCustomerDimensionReport-DATA:" + entry.getValue() + ":"
	// + entry.getKey());
	// dimensionName = entry.getKey();
	// breadCrumbMap = entry.getValue();
	// if (report.getDimension(dimensionName) != null) {
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// } else {
	// for (Entry<String, Object> level : breadCrumbMap.entrySet()) {
	// if (level.getValue() == null) {
	// selectedDimension = dimensionName;
	// selectedLevel = level.getKey();
	// Dimension dimension = new Dimension();
	// dimension.setName(dimensionName);
	// dimension.setNumberOfLevels(1);
	// dimension.setCurrentSelectionName(selectedLevel);
	// report.addDimension(dimension);
	// report.updateBreadCrumb(dimensionName, null);
	// break;
	// } else {
	// Dimension dimension = new Dimension();
	// dimension.setName(dimensionName);
	// dimension.setNumberOfLevels(breadCrumbMap.size());
	// dimension.setCurrentSelectionName(level.getKey());
	// report.addDimension(dimension);
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// }
	// }
	// }
	// }
	//
	// // dimensionName = "DIM_CUSTOMER";
	// // Dimension dimension = new Dimension();
	// // dimension.setName(dimensionName);
	// // dimension.setNumberOfLevels(1);
	// // dimension.setCurrentSelectionName("CUSTOMER_ID");
	// // report.addDimension(dimension);
	// // report.updateBreadCrumb(dimensionName, null);
	//
	// // report.setAsFirstDimension("DIM_CUSTOMER");
	// report.setAsFirstDimension(selectedDimension);
	//
	// List<String> dimList = report.getDimensionList();
	// List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	//
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportData(dimDataMapList, dimList,
	// // report.getAggregateOperation(), false, "DIM_CUSTOMER", String.class);
	// // return factDataMap1;
	//
	// FactDAOMod factDaoMod = new FactDAOMod();
	// Map<String, Float> factDataMap1 = factDaoMod.fetchReportData(dimDataMapList, dimList,
	// report.getAggregateOperation(), false, String.class);
	// return factDataMap1;
	// }
	//
	// @RequestMapping(value = "/getSubStationDimensionReport", method = { RequestMethod.POST,
	// RequestMethod.GET })
	// public @ResponseBody
	// // BreadCrumb getDimensionLevelData3(@RequestBody HashMap<String, String> json,
	// // HttpServletRequest request,
	// Map<String, Float> getSubStationDimensionReport(
	// @RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
	// HttpServletRequest request, HttpServletResponse response, HttpSession session) {
	// logger.info("-----------------------" + "getSubStationDimensionReport()" +
	// "-----------------------");
	// logger.info("getSubStationDimensionReport-JSON:" + json);
	// // //Dimension drillDownDimension;
	// String dimensionName = "";
	// LinkedHashMap<String, Object> breadCrumbMap = null;
	//
	// Report report = loadReport(reportName);
	// //Report report = this.report;
	//
	// for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
	// logger.info("getSubStationDimensionReport-DATA:" +entry.getValue() + ":" + entry.getKey());
	// dimensionName = entry.getKey();
	// breadCrumbMap = entry.getValue();
	// if(report.getDimension(dimensionName)!=null) {
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// }
	// }
	// //logger.info("Report:"+report);
	//
	// //Report report = loadReport(reportName);
	// dimensionName = "DIM_SUBSTATION";
	// Dimension dimension = new Dimension();
	// dimension.setName(dimensionName);
	// dimension.setNumberOfLevels(1);
	// dimension.setCurrentSelectionName("SUBSTATION_ID");
	// report.addDimension(dimension);
	// //report.setDimensionCount(3);
	// report.updateBreadCrumb(dimensionName, null);
	// //System.out.println("REPORT-FORMAT:" + report);
	// //report.setAsFirstDimension(dimensionName);
	//
	// // List<String> dimList = report.getDimensionList();
	// // List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportDataMod1(dimDataMapList, dimList,
	// // report.getAggregateOperation(), String.class);
	//
	// report.setAsFirstDimension(dimensionName);
	// List<String> dimList = report.getDimensionList();
	// List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	//
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportData(dimDataMapList, dimList,
	// // report.getAggregateOperation(), false, dimList.get(0), String.class);
	// // return factDataMap1;
	//
	// FactDAOMod factDaoMod = new FactDAOMod();
	// Map<String, Float> factDataMap1 = factDaoMod.fetchReportData(dimDataMapList, dimList,
	// report.getAggregateOperation(), false, String.class);
	// return factDataMap1;
	// }

	// @RequestMapping(value = "/getCustomerDimensionReport", method = { RequestMethod.POST,
	// RequestMethod.GET })
	// public @ResponseBody
	// Map<String, Float> getCustomerDimensionReport(
	// @RequestBody HashMap<String, LinkedHashMap<String, Object>> json,
	// HttpServletRequest request, HttpServletResponse response, HttpSession session) {
	// logger.info("-----------------------" + "getCustomerDimensionReport()" +
	// "-----------------------");
	// logger.info("getCustomerDimensionReport-JSON:" + json);
	// // //Dimension drillDownDimension;
	// String dimensionName = "";
	// LinkedHashMap<String, Object> breadCrumbMap = null;
	//
	// Report report = loadReport(reportName);
	//
	// for (Entry<String, LinkedHashMap<String, Object>> entry : json.entrySet()) {
	// logger.info("getCustomerDimensionReport-DATA:" +entry.getValue() + ":" + entry.getKey());
	// dimensionName = entry.getKey();
	// breadCrumbMap = entry.getValue();
	// if(report.getDimension(dimensionName)!=null) {
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// } else {
	// Dimension dimension = new Dimension();
	// dimension.setName(dimensionName);
	// dimension.setNumberOfLevels(1);
	// dimension.setCurrentSelectionName("SUBSTATION_ID");
	// report.addDimension(dimension);
	// //report.setDimensionCount(3);
	// //logger.info("getCustomerDimensionReport-BREADCRUMB:" + breadCrumbMap);
	// report.updateBreadCrumb(dimensionName, breadCrumbMap);
	// }
	// }
	//
	// dimensionName = "DIM_CUSTOMER";
	// Dimension dimension = new Dimension();
	// dimension.setName(dimensionName);
	// dimension.setNumberOfLevels(1);
	// dimension.setCurrentSelectionName("CUSTOMER_ID");
	// report.addDimension(dimension);
	// report.updateBreadCrumb(dimensionName, null);
	//
	//
	// //report.setAsFirstDimension("DIM_CUSTOMER");
	// report.setAsFirstDimension(dimensionName);
	// List<String> dimList = report.getDimensionList();
	// List<Map<String, Object>> dimDataMapList = report.getDimensionDataMapList();
	//
	// // FactDAO factDao = new FactDAO();
	// // Map<String, Float> factDataMap1 = factDao.fetchReportData(dimDataMapList, dimList,
	// // report.getAggregateOperation(), false, "DIM_CUSTOMER", String.class);
	// // return factDataMap1;
	//
	// FactDAOMod factDaoMod = new FactDAOMod();
	// Map<String, Float> factDataMap1 = factDaoMod.fetchReportData(dimDataMapList, dimList,
	// report.getAggregateOperation(), false, String.class);
	// return factDataMap1;
	// }
	
	@SuppressWarnings("unchecked")
	public Report loadReport(String reportName) {
		System.out.println("------------------------LOAD REPORT---------------------");
		System.out.println("REPORT-NAME: " + reportName);

		List<String> reportDimensionDetails = utilCommon
				.getReportDimensionDetails(reportName.trim());
		// ??? -Temporary Solution : ReportID stores AggregationFunctionName
		String reportAggergateFunction = utilCommon.getReportAggregateFunction(
				reportName.trim());

		System.out.println("AGGREGATE-FUNCTION...."+reportAggergateFunction);
		
		//Report report = new Report();
		report = new Report();
		report.setName(reportName.trim());
		//commented later for dimension swapping
		//report.setDimensionCount(reportDimensionDetails.size());
		report.setAggregateOperation(reportAggergateFunction);

		for (String reportDim : reportDimensionDetails) {
			System.out.println("reportDim value is ........"+reportDim);
			String params[] = reportDim.split(",");
			String topLevelSelectionName = utilCommon.getHierarchyLevelName(
					params[0].trim(), params[1].trim());
			ArrayList<String> hierarchyList = (ArrayList<String>) utilCommon
					.getHierarchyMetaData().get(params[0].trim());

			// ??? - Ideally in the next function call currentLevelMap CAN'T BE NULL if
			// currentSelectionHierarchy > 1. In this case the higher level hierarchy values MUST be
			// configured through .xml file
			System.out.println("topLevelSelectionName value is...."+topLevelSelectionName);
			List<String> topLevelSelectionValues = utilCommon.getSelectionValues(
					params[0].trim(), topLevelSelectionName, null);
			String topLevelSelectionValue;

			// if (topLevelSelectionValues.size() > 1) {
			// topLevelSelectionValue = "All";
			// topLevelSelectionValues.add(0, "All");
			// } else {
			// topLevelSelectionValue = topLevelSelectionValues.get(0);
			// }

			topLevelSelectionValue = topLevelSelectionValues.get(0);

			Dimension dimension = new Dimension();
			dimension.setNumberOfLevels(hierarchyList.size());
			dimension.setHierarchyLevels(hierarchyList);
			dimension.setName(params[0].trim());
			dimension.setDisplayType(params[2].trim());
			dimension.setCurrentSelectionName(topLevelSelectionName);
			dimension.setCurrentSetOfValues(topLevelSelectionValues);
			dimension.setCurrentSelectionValue(topLevelSelectionValue);
			report.addDimension(dimension);
		}
		return report;
	}
}
